package com.andox.fn.inf.rpc.rest;

import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

/**   
 * @ClassName:   RefreshHandlerMapping   
 * @author:      Andox
 * @date:        2019年7月29日 下午6:12:12   
 *     
 */

public class HandlerMappingRefresher implements InitializingBean, ApplicationContextAware, ApplicationListener<ContextRefreshedEvent> {
	private ApplicationContext applicationContext;
	private RequestMappingHandlerMapping handlerMapping;
	
	public void refresh(Object controller) {
		try {
			Method me = AbstractHandlerMethodMapping.class.getDeclaredMethod("detectHandlerMethods", new Class<?>[] {Object.class});
			me.setAccessible(true);
			ReflectionUtils.invokeMethod(me, handlerMapping, controller);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	@Override
	public void afterPropertiesSet() throws Exception {
		handlerMapping = this.applicationContext.getBean(RequestMappingHandlerMapping.class);
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		if (event == null)
			return;
		
		Map<String, RestControllerMark> beans = this.applicationContext.getBeansOfType(RestControllerMark.class);
		for (Iterator<String> it = beans.keySet().iterator(); it.hasNext(); ) {
			String beanName = it.next();
			RestControllerMark controller = beans.get(beanName);
			refresh(controller);
		}
	}
}
